/** ****************************************************************************
@defgroup Beeper Beeper
@ingroup BSP_External
@brief 蜂鸣器驱动
@addtogroup Beeper
@{
*******************************************************************************/

#ifndef _BEEPER_H_
#define _BEEPER_H_

#include "stdc.h"
#include "switch.h"
#include "share/notes_music.h"


/// 无源蜂鸣器驱动类
typedef struct {
	FUNC_GPIO_ConfigAsPwm funcPwmStart;
	FUNC_GPIO_PwmStop funcPwmStop;

	switch_state_t state;
    OSTaskId blinkTaskId;			///< 闪烁任务ID
    uint32_t blinkExOnTime;    			///< 闪烁亮的时间
	
	uint32_t freq;						///< 默认频率
	uint8_t duty;						///< 默认占空比	
	OSTaskId routineCheckTaskId;	///< 例行任务ID
	uint16_t keepTime;
	uint32_t startTime;
	const Note *note;
	uint16_t speed;
} driver_beeper_t;

/**
 * @brief 初始化
 * @param dev 驱动数据结构指针
 * @param freq 默认频率(Hz)
 * @param duty 默认占空比(%)
 */
void beeper_init(driver_beeper_t* dev, uint32_t freq, uint8_t duty);

/// @brief 开关到指定状态
/// @param state: 0-OFF; 1-ON; 0xFF-REVERSE;
/// @return 状态是否变化了
bool beeper_switchTo(driver_beeper_t* dev, switch_state_t state, uint32_t keepTime1, uint32_t keepTime2, uint8_t flashTimes);

/// @brief 亮
inline static bool beeper_on(driver_beeper_t* dev) { return beeper_switchTo(dev, SWITCH_ON, 0, 0, 0); }
/// @brief 灭
inline static bool beeper_off(driver_beeper_t* dev) { return beeper_switchTo(dev, SWITCH_OFF, 0, 0, 0); }
/// @brief 状态反转
inline static bool beeper_toggle(driver_beeper_t* dev) { return beeper_switchTo(dev, SWITCH_TOGGLE, 0, 0, 0); }
/// @brief 取得当前状态
inline static switch_state_t beeper_getState(driver_beeper_t* dev) { return dev ? dev->state : SWITCH_OFF; }

/// @brief 闪一下
/// @param time: 保持时间, ms
void beeper_blink(driver_beeper_t* dev, uint16_t time);

/// @brief 闪多下
/// @param onTime: 点亮时间, ms
/// @param offTime: 关闭时间, ms
/// @param count: 闪几次；=OSTASK_REPEAT_FOREVER 表示永远闪烁
/// @retval taskId, 可通过 osTaskKill() 来停止闪烁
OSTaskId beeper_blinkEx(driver_beeper_t* dev, uint16_t onTime, uint16_t offTime, uint16_t count);

/// @brief 停止闪烁及播放
void beeper_stop(driver_beeper_t* dev);

/// @brief 播放音乐
/// @param note 音乐
/// @param speed 速率(%)
bool beeper_play(driver_beeper_t* dev, const Note *note, uint16_t speed);


#endif  // _BEEPER_H_
